package py.com.erpone.session.dm;

import java.util.ArrayList;
import java.util.List;

import javax.ejb.LocalBean;
import javax.ejb.Stateful;
import javax.enterprise.context.Conversation;
import javax.enterprise.context.ConversationScoped;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.event.ValueChangeEvent;
import javax.inject.Inject;
import javax.inject.Named;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.PersistenceContextType;

import org.primefaces.context.RequestContext;
import org.primefaces.event.CloseEvent;

import py.com.erpone.entity.dm.Ciudad;
import py.com.erpone.entity.dm.Contacto;
import py.com.erpone.entity.dm.Pais;
import py.com.erpone.entity.dm.Proveedor;
import py.com.erpone.session.dm.list.CiudadList;
import py.com.erpone.util.LocaleSelector;

@Stateful
@Named
@LocalBean
@ConversationScoped
public class ProveedorBean {

	@PersistenceContext(type = PersistenceContextType.EXTENDED)
	private EntityManager em;

	@Inject
	private Conversation conversation;
	
	//Se declara para utilizar los métodos que retornan listas de la Clase CiudadList
	@Inject
	private CiudadList ciudadList;
	
	//Solo sirve para imprimir los mensajes.
	@Inject
	private LocaleSelector localeSelector;
	  
	//Se crea la referencia a la clase Proveedor para poder utilizar sus atributos.
	//Se debe crear getter y setter para utilizarlo desde la página xhtml.
	private Proveedor proveedor;

	//Se crea la referencia a la clase Contactos para poder almacenar los valores de los inputs introducidos desde la pagina xhtml, se usa, se agrega en la lista y se setea su valor.
	private Contacto contacto;

	//Sirve para obtener el indice del objeto que se recibió de la lista de contactos (UI)
	private int indexContact;
		
    //Es una varialbe referenciado a una lista de ciudades donde se almacenará el valor temporal del combo de acuerdo al pais seleccionado
	private List<Ciudad> clCombo;
	
	private boolean flag = false;
	
	
	//GETTERS AND SETTERS
	public int getIndexContact() {
		return indexContact;
	}

	public void setIndexContact(int indexContact) {
		this.indexContact = indexContact;
	}


	public CiudadList getCiudadList() {
		return ciudadList;
	}

	public void setCiudadList(CiudadList ciudadList) {
		this.ciudadList = ciudadList;
		
	}

	public List<Ciudad> getClCombo() {
		return clCombo;
	}

	public void setClCombo(List<Ciudad> clCombo) {
		this.clCombo = clCombo;
	}

	public Contacto getContacto() {
		return contacto;
	}

	public void setContacto(Contacto contacto) {
		this.contacto = contacto;
	}

	public Proveedor getProveedor() {
		return proveedor;
	}

	public void setProveedor(Proveedor proveedor) {
		this.proveedor = proveedor;
	}

	public void selectOneMenuListener(ValueChangeEvent v){
		 setClCombo(ciudadList.findAllCityByCountry((Pais) v.getNewValue()));
	}
    //Se asocia un proveer al contacto y con los valores recibidos de los inputs; se agrega a la lista de contactos perteneciente a dicho proveedor
	//Si el flag es true quiere decir que paso por el metodo SetContactoAModificar, es una modificación, sino agrega un nuevo registro.
	public void addNewContact() {
		if (flag){
			proveedor.getContactos().set(indexContact, contacto);
	        FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, localeSelector.getMensaje("contacto_actualizado"), proveedor.getNombre()));		
			flag = false;
		}else{
			contacto.setProveedor(proveedor);
			proveedor.getContactos()
					.add(contacto);
			FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, localeSelector.getMensaje("contacto_nuevo"), proveedor.getNombre()));
		}
		contacto = new Contacto();	
		}
	
	public void cancelarContact(){
		this.flag = false;
		contacto = new Contacto();
	}
	public void setContactoAModificar(Contacto contactoAModificar) {
		this.flag = true;
		this.setContacto(contactoAModificar);
		//Al presionar en el botón modificar, recibe el valor perteneciente, setea la variable contacto
		// indexContact cargando el valor del indice del objeto recibido
		this.indexContact = proveedor.getContactos().indexOf(contacto);		
	}

	public void removeContact(Contacto contact){
		Contacto contacto = contact;
		proveedor.getContactos().remove(contacto);
        FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, localeSelector.getMensaje("contacto_eliminado"), proveedor.getNombre()));		
	}

	
	public void iniciar() {
		if (conversation.isTransient())
			conversation.begin();
		proveedor = new Proveedor();
		contacto = new Contacto();
		proveedor.setCiudad(new Ciudad());
		proveedor.setContactos(new ArrayList<Contacto>());
	}

	public void iniciar(Proveedor proveedor) {
		
		if (conversation.isTransient())
			conversation.begin();
		contacto = new Contacto();
		this.proveedor=em.find(Proveedor.class, proveedor.getId());
		this.clCombo = ciudadList.findAllCityByCountry(this.proveedor.getCiudad().getPais());		
	}
	public boolean checkContactosEmpty(){
		boolean empty = false;
	    if (proveedor.getContactos().isEmpty()){
	    	empty = true;
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, localeSelector.getMensaje("proveedor_error"), proveedor.getNombre()));
	    }
		return empty;
	}

	public void guardar() {
		//Solo si es true pregunta por el id para ver si existe (actualiza) o no (persiste).		  //En caso que exista, persiste, imprime el mensaje  de suceso y retorna a lista de proveedores
		if(!checkContactosEmpty()){
		  if (proveedor.getId() == null) {					
			    em.persist(proveedor);
	            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, localeSelector.getMensaje("proveedor_nuevo"), proveedor.getNombre()));	           
		   }else{
			    em.merge(proveedor);
	            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, localeSelector.getMensaje("proveedor_actualizado"), proveedor.getNombre()));	            
           }
		  if (!conversation.isTransient())
  			conversation.end();
		  //El dialog solo se cierra si la lista de contactos y todos los demás campos se completaron
		  //Se mezcla la lógica de negocio con la vista (xhtml), buscar otra alternativa
		  RequestContext rc = RequestContext.getCurrentInstance();
		  rc.execute("dlg.hide()"); 
		  RequestContext.getCurrentInstance().update("formPrincipal");
		}
	}
	public void eliminar(Proveedor proveedor) {
		em.remove(em.merge(proveedor));
        FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, localeSelector.getMensaje("proveedor_eliminado"), proveedor.getNombre()));
		if (!conversation.isTransient())
			conversation.end();
	}

	public void cancelar() {
		if (!conversation.isTransient())
			conversation.end();
	}
	
}
